package com.sunwayhorizo.health.platform.security.service.permission;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.platform.base.BaseManager;
import com.sunwayhorizo.health.platform.common.PlatformConstant;
import com.sunwayhorizo.health.platform.security.dao.SecurityPermissionDao;
import com.sunwayhorizo.health.platform.security.dao.SecurityResourceDao;
import com.sunwayhorizo.health.platform.security.persistent.SecurityPermission;
import com.sunwayhorizo.health.platform.security.persistent.SecurityPermissionRole;
import com.sunwayhorizo.health.platform.security.persistent.SecurityResource;

@Name("SecurityResourceManager")
@Stateless
public class SecurityResourceManager extends BaseManager implements SecurityResourceManagerLocal
{

    public ResultsDTO newSecurityResource(SecurityResource resource)
    {
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        resourceDao.newSecurityResource(resource);
        return super.getResultsDTO("新增资源列表成功", true, resource.getResourceId());
    }

    public ResultsDTO delSecurityResource(List<String> list)
    {
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        if (ListUtil.isNotEmpty(list))
        {
            for (String resourceIdVar : list)
            {
                if ( !this.isDeletableResourceById(resourceIdVar) )
                {
                    return super.getResultsDTO("菜单被其他地方关联，请删除关联后再次请求", false, null);
                }
            }
        }
        SecurityPermissionDao permissionDao = (SecurityPermissionDao) Component.getInstance("SecurityPermissionDao");
        permissionDao.deleteSecurityPermissionByResourceIds(list);
        resourceDao.deleteSecurityResource(list);
        return super.getResultsDTO("删除资源列表成功", true, null);
    }

    public ResultsDTO updateSecurityResource(SecurityResource resource)
    {
        SecurityPermissionDao permissionDao = (SecurityPermissionDao) Component.getInstance("SecurityPermissionDao");
        permissionDao.deleteSecurityPermissionByResourceId(resource.getResourceId());

        if (resource.getPermissions() != null)
        {
            for (SecurityPermission p : resource.getPermissions())
            {
                p.setPermissionId(null);
            }
        }
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        resourceDao.updateSecurityResource(resource);
        return super.getResultsDTO("修改资源列表成功", true, null);
    }

    public ResultsDTO findSecurityResourceList()
    {
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        return super.getResultsDTO("查询资源列表成功", true, resourceDao.findSecurityResourceList());
    }

    public ResultsDTO findSecurityResourceListWithOutRootNode()
    {
        List<SecurityResource> list = ((SecurityResourceDao) Component.getInstance("SecurityResourceDao")).findSecurityResourceListWithOutRootNode();
        return super.getResultsDTO("查询根节点之外的资源列表成功", true, list);
    }

    public ResultsDTO findSecurityResourceDetailById(String resourceId)
    {
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        return super.getResultsDTO("查询资源列表成功", true, resourceDao.findSecurityResourceDetailById(resourceId));
    }

    public ResultsDTO findSecurityResourceTree()
    {
        List<SecurityResource> result = new ArrayList<SecurityResource>();
        List<SecurityResource> list = ((SecurityResourceDao) Component.getInstance("SecurityResourceDao")).findSecurityResourceListWithFatherResource();
        result.add(init(list));
        super.entityManager2.clear();
        return super.getResultsDTO("查询菜单功能树成功", true, result);
    }

    public ResultsDTO findSecurityResourceListByRoleId(String roleId)
    {
        List<SecurityResource> resourceResult = new ArrayList<SecurityResource>();

        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        List<SecurityPermissionRole> permissionRoles = resourceDao.findSecurityResourceListByRoleId(roleId);
        Map<String, List<SecurityPermission>> resourceIdOpeartionListMap = new HashMap<String, List<SecurityPermission>>();
        Map<String, SecurityResource> resourceIdResourceMap = new HashMap<String, SecurityResource>();
        for (int i = 0; i < permissionRoles.size(); i++)
        {
            SecurityPermissionRole spr = permissionRoles.get(i);
            if (spr.getPermission()!=null && spr.getPermission().getResource() != null)
            {
                resourceIdResourceMap.put(spr.getPermission().getResource().getResourceId(), spr.getPermission().getResource());
                if (resourceIdOpeartionListMap.get(spr.getPermission().getResource().getResourceId()) == null)
                {
                    resourceIdOpeartionListMap.put(spr.getPermission().getResource().getResourceId(), new ArrayList<SecurityPermission>());
                }
                resourceIdOpeartionListMap.get(spr.getPermission().getResource().getResourceId()).add(spr.getPermission());
            }
        }

        for (String resourceId : resourceIdResourceMap.keySet())
        {
            resourceIdResourceMap.get(resourceId).setPermissions(resourceIdOpeartionListMap.get(resourceId));
            resourceResult.add(resourceIdResourceMap.get(resourceId));
        }
        super.entityManager2.clear();
        return super.getResultsDTO("通过角色查询资源成功", true, resourceResult);
    }

    //查看树
    public ResultsDTO findSecurityResourceTreeByRoleId(String roleId)
    {
        List<SecurityResource> result = new ArrayList<SecurityResource>();
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        SecurityPermissionDao permissionDao = (SecurityPermissionDao) Component.getInstance("SecurityPermissionDao");

        List<SecurityResource> resouceAll = resourceDao.findSecurityResourceListWithFatherResource();
        List<SecurityPermissionRole> permissionRoleListByRoleId = permissionDao.findSecurityPermissionListByRoleId(roleId);

        Map<String, SecurityResource> resourceMapLeft = new HashMap<String, SecurityResource>();
        for (SecurityPermissionRole permissionRoleByRoleId : permissionRoleListByRoleId)
        {
            SecurityPermission permissionByRoleId = permissionRoleByRoleId.getPermission();
            if (permissionByRoleId == null)
            {
                continue;
            }
            permissionByRoleId.getResource().setPermissions(new ArrayList<SecurityPermission>());
            resourceMapLeft.put(permissionByRoleId.getResource().getResourceId(), permissionByRoleId.getResource());
            if (permissionByRoleId.getResource().getFatherResource() != null)
            {
                permissionByRoleId.getResource().getFatherResource().setPermissions(new ArrayList<SecurityPermission>());
                resourceMapLeft.put(permissionByRoleId.getResource().getFatherResource().getResourceId(), permissionByRoleId.getResource()
                    .getFatherResource());
            }
        }
        Iterator<SecurityResource> allResourceIt = resouceAll.iterator();
        while (allResourceIt.hasNext())
        {
            SecurityResource sr = allResourceIt.next();
            if (sr.getResourceId().equals(PlatformConstant.ROOT_RESOURCE))
            {
                continue;
            }
            if (resourceMapLeft.get(sr.getResourceId()) == null)
            {
                allResourceIt.remove();
            }
            else
            {
                for (SecurityPermissionRole pr : permissionRoleListByRoleId)
                {
                    SecurityPermission p = pr.getPermission();
                    if (p != null && p.getResource().getResourceId().equals(sr.getResourceId()))
                    {
                        sr.getPermissions().add(p);
                    }
                }
            }
        }
        result.add(init(resouceAll));
        super.entityManager2.clear();
        return super.getResultsDTO("根据角色查询菜单功能树成功", true, result);
    }

    public ResultsDTO findSecurityResourceTreeByAccountIdJoinRole(String accountId)
    {
        List<SecurityResource> result = new ArrayList<SecurityResource>();
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        SecurityPermissionDao permissionDao = (SecurityPermissionDao) Component.getInstance("SecurityPermissionDao");

        List<SecurityResource> resouceAll = resourceDao.findSecurityResourceListWithFatherResource();
        List<SecurityPermission> permissionListByAccountId = permissionDao.findSecurityPermissionListByAccountIdJoinRole(accountId);
        permissionListByAccountId.addAll(permissionDao.findSecurityPermissionListByAccountId(accountId));

        Map<String, SecurityResource> resourceMapLeft = new HashMap<String, SecurityResource>();
        for (SecurityPermission permissionByRoleId : permissionListByAccountId)
        {
            if (permissionByRoleId == null)
            {
                continue;
            }
            permissionByRoleId.getResource().setPermissions(new ArrayList<SecurityPermission>());
            resourceMapLeft.put(permissionByRoleId.getResource().getResourceId(), permissionByRoleId.getResource());
            if (permissionByRoleId.getResource().getFatherResource() != null)
            {
                permissionByRoleId.getResource().getFatherResource().setPermissions(new ArrayList<SecurityPermission>());
                resourceMapLeft.put(permissionByRoleId.getResource().getFatherResource().getResourceId(), permissionByRoleId.getResource()
                    .getFatherResource());
            }
        }
        Iterator<SecurityResource> allResourceIt = resouceAll.iterator();
        while (allResourceIt.hasNext())
        {
            SecurityResource sr = allResourceIt.next();
            if (sr.getResourceId().equals(PlatformConstant.ROOT_RESOURCE))
            {
                continue;
            }
            if (resourceMapLeft.get(sr.getResourceId()) == null)
            {
                allResourceIt.remove();
            }
            else
            {
                for (SecurityPermission p : permissionListByAccountId)
                {
                    if (p != null && p.getResource().getResourceId().equals(sr.getResourceId()))
                    {
                        sr.getPermissions().add(p);
                    }
                }
            }
        }
        result.add(init(resouceAll));
        super.entityManager2.clear();
        return super.getResultsDTO("根据账号查询菜单授权功能树成功", true, result);
    }

    public ResultsDTO findSecurityResourceTreeByAccountIdJoinRoleWithScreen(String accountId)
    {
        List<SecurityResource> result = new ArrayList<SecurityResource>();
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        SecurityPermissionDao permissionDao = (SecurityPermissionDao) Component.getInstance("SecurityPermissionDao");

        List<SecurityResource> resouceAll = resourceDao.findSecurityResourceListWithFatherResource();
        List<SecurityPermission> permissionListByAccountId = permissionDao.findSecurityPermissionListByAccountIdJoinRoleWithScreen(accountId);
        permissionListByAccountId.addAll(permissionDao.findSecurityPermissionListByAccountIdWithScreen(accountId));

        Map<String, SecurityResource> resourceMapLeft = new HashMap<String, SecurityResource>();
        for (SecurityPermission permissionByRoleId : permissionListByAccountId)
        {
            if (permissionByRoleId == null)
            {
                continue;
            }
            permissionByRoleId.getResource().setPermissions(new ArrayList<SecurityPermission>());
            resourceMapLeft.put(permissionByRoleId.getResource().getResourceId(), permissionByRoleId.getResource());
            if (permissionByRoleId.getResource().getFatherResource() != null)
            {
                permissionByRoleId.getResource().getFatherResource().setPermissions(new ArrayList<SecurityPermission>());
                resourceMapLeft.put(permissionByRoleId.getResource().getFatherResource().getResourceId(), permissionByRoleId.getResource()
                    .getFatherResource());
            }
        }
        Iterator<SecurityResource> allResourceIt = resouceAll.iterator();
        while (allResourceIt.hasNext())
        {
            SecurityResource sr = allResourceIt.next();
            if (sr.getResourceId().equals(PlatformConstant.ROOT_RESOURCE))
            {
                continue;
            }
            if (resourceMapLeft.get(sr.getResourceId()) == null)
            {
                allResourceIt.remove();
            }
            else
            {
                for (SecurityPermission p : permissionListByAccountId)
                {
                    if (p != null && p.getResource().getResourceId().equals(sr.getResourceId()))
                    {
                        sr.getPermissions().add(p);
                    }
                }
            }
        }
        result.add(init(resouceAll));
        super.entityManager2.clear();
        return super.getResultsDTO("根据账号查询屏蔽后的菜单授权功能树成功", true, result);
    }

    public ResultsDTO validateUniqueSecurityResource(String resourceId, String resourceName)
    {
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        try
        {
            SecurityResource dbResourceByName = resourceDao.findSecurityResourceDetailByName(resourceName);
            if (StrUtil.isEmpty(resourceId))
            {
                return super.getResultsDTO("资源名称已经存在", false, null);
            }
            else
            {
                if (resourceId.equals(dbResourceByName.getResourceId()))
                {
                    return super.getResultsDTO("资源名称可以使用", true, null);
                }
                else
                {
                    return super.getResultsDTO("资源名称已经存在", false, null);
                }
            }
        }
        catch (Exception e)
        {
            return super.getResultsDTO("资源名称可以使用", true, null);
        }
    }

    public ResultsDTO findSecurityPermissionListByResourceId(String resourceId)
    {
        SecurityPermissionDao permissionDao = (SecurityPermissionDao) Component.getInstance("SecurityPermissionDao");
        return super.getResultsDTO("查询权限列表成功", true, permissionDao.findSecurityPermissionListByResourceId(resourceId));
    }

    private SecurityResource init(List<SecurityResource> list)
    {
        Map<String, SecurityResource> map = new LinkedHashMap<String, SecurityResource>();
        for (SecurityResource r : list)
        {
            map.put(r.getResourceId(), r);
        }
        return initTree(map);
    }

    private SecurityResource initTree(Map<String, SecurityResource> treeResource)
    {
        for (String key : treeResource.keySet())
        {
            SecurityResource sub = treeResource.get(key);
            SecurityResource father = sub.getFatherResource();
            if (father != null)
            {
                father.addChild(sub);
                treeResource.put(father.getResourceId(), father);
            }
        }
        return treeResource.get(PlatformConstant.ROOT_RESOURCE);
    }
    
    /**
     * 通过资源Id查询资源是否被使用
     * @param resourceId 实体ID
     * @return 返回是否可删除，true为可删除，false不可删除
     */
    private boolean isDeletableResourceById(String resourceId) {
        SecurityResourceDao resourceDao = (SecurityResourceDao) Component.getInstance("SecurityResourceDao");
        //如果权限表中找不到资源，说明可以直接删除
        if( resourceDao.findSecurityResourceListSizeByResourceId(resourceId) == 0 ){
            return true;
        }else{
            if( resourceDao.findSecurityResourceListSizeNotExistsInPermissionRoleByResourceId(resourceId) == 0){
                return false;
            }
            if( resourceDao.findSecurityResourceListSizeNotExistsInPermissionAccountByResourceId(resourceId) == 0 ){
                return false;
            }
            if( resourceDao.findSecurityResourceListSizeNotExistsInAccountRolePermissionByResourceId(resourceId) == 0 ){
                return false;
            }
            return true;
        }
    }
}
